<!--
 * @Description: 账户管理
 * @Author: 0001100986/LiuShuai
 * @Date: 2021-06-10 14:26:28
 * @LastEditTime: 2021-10-11 15:58:01
 * @LastEditors: 0001101008/HuYuxi
-->
<template>
  <div class="page-content">
    <table-bar :showTop="false" :columns="columns" @changeColumn="changeColumn">
      <div slot="top">
        <el-form :model="filterSearch" label-width="80px" label-position="right">
          <el-row :gutter="20">
            <el-col :xs="24" :sm="12" :lg="6">
              <!-- 用户名称 -->
              <el-form-item label="用户名称">
                <el-input v-model.trim="filterSearch.userName" placeholder="名称"></el-input>
              </el-form-item>
            </el-col>
            <el-col :xs="24" :sm="12" :lg="6">
              <!-- 租户名称 -->
              <el-form-item label="租户名称">
                <el-input v-model.trim="filterSearch.tenantName" placeholder="名称"></el-input>
              </el-form-item>
            </el-col>
            <el-row :xs="24" :sm="12" :lg="6" style="float: right; margin-right: 10px;">
              <!-- 搜索  重置-->
              <el-button type="primary" @click="search">搜索</el-button>
              <el-button @click="reset">重置</el-button>
            </el-row>
          </el-row>
        </el-form>
      </div>
      <div slot="bottom">
        <!-- 新增 -->
        <el-button size="medium" type="primary" plain @click="showDialog('add')" v-power="2">新建</el-button>
        <!-- 账户恢复 -->
        <el-button
          size="medium"
          type="success"
          plain
          @click="accountAll"
          style="margin-left: 0;"
          v-power="2"
        >恢复</el-button>
      </div>
    </table-bar>
    <tao-table
      class="table-box"
      :data="dataList"
      :page="page"
      @changePage="changePage"
      :showPage="true"
      ref="table"
    >
      <!-- 用户名称 -->
      <el-table-column
        v-if="columns[0].show"
        align="center"
        width="200"
        label="用户名称"
        show-overflow-tooltip
        prop="username"
      />
      <!-- 租户名称 -->
      <el-table-column
        v-if="columns[1].show"
        align="center"
        width="150"
        label="租户名称"
        show-overflow-tooltip
        prop="dgName"
      />
      <!-- 显示名称 -->
      <el-table-column
        v-if="columns[2].show"
        align="center"
        width="200"
        label="显示名称"
        show-overflow-tooltip
        prop="userlabel"
      />
      <!-- 状态 -->
      <el-table-column
        v-if="columns[3].show"
        label="状态"
        sortable
        align="center"
        width="150"
        show-overflow-tooltip
        prop="state"
      >
        <template slot-scope="scope">{{filterStatus(scope.row)}}</template>
      </el-table-column>
      <!-- API令牌 -->
      <el-table-column
        v-if="columns[4].show"
        label="API令牌"
        align="center"
        width="330"
        prop="apiToken"
      >
        <template slot-scope="scope">
          {{scope.row.apiToken}}
          <el-tag
            size="medium"
            type="info"
            @click.native="copyToken(scope.row.apiToken)"
            v-show="scope.row.apiToken"
          >
            <i class="el-icon-document-copy"></i>
          </el-tag>
        </template>
      </el-table-column>
      <!-- 角色 -->
      <el-table-column
        v-if="columns[5].show"
        min-width="300"
        label="角色"
        show-overflow-tooltip
        prop="cnRoleName"
      >
        <template slot-scope="scope">{{ scope.row.cnRoleName | filterRole}}</template>
      </el-table-column>
      <!-- 邮箱 -->
      <el-table-column
        v-if="columns[6].show"
        align="left"
        show-overflow-tooltip
        min-width="200"
        label="邮箱"
        prop="email"
      />
      <!-- 操作 编辑 删除-->
      <el-table-column fixed="right" align="center" label="操作" width="220px">
        <template slot-scope="scope">
          <el-button
            type="text"
            icon="el-icon-edit"
            @click="showDialog('edit', scope)"
            v-power="scope.row.dgId === 100000 ? 0 : 2"
          >编辑</el-button>
          <el-button
            type="text"
            style="color: #FA6962"
            icon="el-icon-delete"
            @click="deleteUser(scope)"
            v-power="scope.row.dgId === 100000 ? 0 : 2"
          >删除</el-button>
          <el-button
            type="text"
            style="color: #67C23A"
            icon="el-icon-unlock"
            @click="unlock(scope)"
            v-power="scope.row.dgId === 100000 ? 0 : 2"
          >解锁</el-button>
        </template>
      </el-table-column>
    </tao-table>
    <el-dialog
      :title="dialogTitle"
      :close-on-click-modal="false"
      width="500px"
      :visible.sync="dvEdit"
    >
      <el-form
        ref="ruleForm"
        :model="form"
        :rules="rules"
        label-width="80px"
        label-position="right"
      >
        <!-- 用户名称 编辑 -->
        <el-form-item label="用户名称" prop="username">
          <el-input v-model="form.username" :disabled="dialogTitle === '编辑'" maxlength="100" />
        </el-form-item>
        <!-- 显示名称 -->
        <el-form-item label="显示名称" prop="userlabel">
          <el-input v-model="form.userlabel" maxlength="50" />
        </el-form-item>
        <!-- 密码 -->
        <el-form-item label="密码" prop="password">
          <el-input v-model="form.password" type="password" maxlength="14" />
        </el-form-item>
        <!-- 租户 请输入关键词-->
        <el-form-item label="租户" prop="tenant">
          <el-select v-model="form.tenant" filterable style="width:100%">
            <el-option
              v-for="item in tenantArry"
              :key="item.id"
              :value="item.id"
              :label="item.userlabel"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- 角色 -->
        <el-form-item label="角色" prop="role">
          <el-select v-model="form.role" style="width:100%">
            <el-option
              v-for="item in roleArry"
              :key="item.role"
              :value="item.roleKey"
              :label="item.roleName + ' - ' +item.description"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- API令牌-->
        <el-form-item label="API令牌" prop="apiToken">
          <el-input v-model="form.apiToken" readonly>
            <el-button slot="append" @click="getAPIToken">Token</el-button>
          </el-input>
        </el-form-item>
        <!-- 邮箱 -->
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="form.email"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="onSubmit">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import _ from 'lodash';
import crypto from '@/utils/crypto';
export default {
  data () {
    // 验证密码
    let valPwd = (rule, value, callback) => {
      let _this = this;
      if (value === '' || value === null || value === undefined) {
        if (this.dialogTitle === '新建') {
          callback(new Error('请输入密码'));
        } else {
          callback();
        }
      } else {
        let pwd = _this.form.password;
        // 正则
        let i = /[0-9]+/;
        let str = /[A-Za-z]/;
        let spec = /[,.<>{}~!@#$%^&*]/;
        if (pwd.length > 5 && pwd.length < 15) {
          if (!i.test(pwd)) {
            callback(new Error('密码不符合规范，必须包含数字!'));
          }
          if (!str.test(pwd)) {
            callback(new Error('密码不符合规范，必须包含字母!'));
          }
          if (!spec.test(pwd)) {
            callback(new Error('密码不符合规范，必须包含 !@#$%^&* 其中一个或多个!'));
          } else {
            callback();
          }
        } else {
          callback(new Error('密码长度不符合规范，范围：6-14位！'));
        }
      }
    };
    return {
      dvEdit: false,
      loading: false,
      tenantArry: [],
      dialogTitle: '',
      page: {
        page: 1,
        pageSize: 15,
        total: 0
      },
      oldform: {},
      form: {
        username: null,
        userlabel: null,
        password: null,
        tenant: [],
        role: null,
        apiToken: null,
        email: null
      },
      dataList: [],
      filterSearch: {
        userName: null,
        tenantName: null
      },
      columns: [
        { name: '用户名称', show: true },
        { name: '租户名称', show: true },
        { name: '显示名称', show: true },
        { name: '状态', show: true },
        { name: 'API令牌', show: true },
        { name: '角色', show: true },
        { name: '邮箱', show: true }
      ],
      roleArry: [],
      rules: {
        username: [
          { required: true, message: '请输入用户名称', trigger: 'blur' },
          { pattern: /^[A-Za-z0-9]+$/, message: '输入不合法，英文/数字', trigger: 'blur' }
        ],
        userlabel: [
          { required: true, message: '请输入显示名称', trigger: 'blur' },
          { pattern: /^[\u4E00-\u9FA5A-Za-z0-9]+$/, message: '输入不合法，中文/英文/数字', trigger: 'blur' }
        ],
        password: [
          { required: true, validator: valPwd, trigger: 'blur' }
        ],
        tenant: [
          { required: true, message: '请选择租户', trigger: 'change' }
        ],
        role: [
          { required: true, message: '请选择角色', trigger: 'change' }
        ],
        email: [
          { required: true, message: '请输入邮箱地址', trigger: 'blur' },
          { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
        ]
      }
    };
  },
  mounted () {
    let _this = this;
    _this.$nextTick(() => {
      _this.refresh();
    });
  },
  filters: {
    // 过滤角色
    filterRole (val) {
      if (val === '系统维护员') {
        val = '系统维护员，二级维护，具备本租户的资源监控权限，以及一级租户的网元监控权限';
      }
      if (val === '超级管理员') {
        val = '超级管理员，一级管理，具备所有资源的管理，监控权限';
      }
      if (val === '外部系统API用户') {
        val = '外部系统API用户，该角色无任何默认功能权限，必须通过[功能许可指定]。资源权限须配置分权分域';
      }
      if (val === '系统操作员') {
        val = '系统操作员，可进行一般的配置修改，不能对管理系统本身进行备份恢复等维护工作，不能修改敏感的资源配置信息';
      }
      if (val === '安全管理员') {
        val = '安全管理员，进行安全数据维护、调整资源所属组织，无业务相关权限';
      }
      if (val === '系统管理员') {
        val = '系统管理员，二级管理，具备本租户的资源管理，监控权限，以及一级租户的网元监控权限';
      }
      if (val === '系统监控员') {
        val = '系统监控员，可对网络信息进行浏览';
      }
      return val;
    }
  },
  watch: {
    dialogTitle: {
      handler: function(newValue, oldValue) {
        if (newValue === '编辑') {
          this.oldform = JSON.parse(sessionStorage.getItem('oldform'));
        }
      },
      deep: true
    }
  },
  methods: {
    // 过滤用户状态
    filterStatus (val) {
      // 存储状态
      let status = [];
      if (val.accountExpired === true) {
        status.push('账户超期');
      }
      if (val.enabled === false) {
        status.push('禁用');
      }
      if (val.passwordExpired === true) {
        status.push('密码过期');
      }
      if (val.accountLocked === true) {
        status.push('账户锁定');
      }
      if (status.length === 0) {
        val.state = '正常';
      } else {
        val.state = _.join(status, '，');
      }
      return val.state;
    },
    // 重新生成api令牌
    async getAPIToken () {
      await this.$http.get({
        url: '/api/gateway/user/token'
      }).then(res => {
        this.form.apiToken = res;
      });
    },
    // 搜索
    search () {
      let _this = this;
      _this.page.page = 1;
      _this.refresh();
    },
    // 复制
    copyToken (val) {
      let copyipt = document.createElement('input');
      copyipt.setAttribute('value', val);
      document.body.appendChild(copyipt);
      copyipt.select();
      document.execCommand('copy');
      document.body.removeChild(copyipt);
      this.$message.success({
        message: '复制成功！',
        duration: 1500
      });
    },
    // 重置
    reset () {
      let _this = this;
      _this.page.page = 1;
      _this.filterSearch = {
        userName: null,
        tenantName: null
      };
      _this.refresh();
    },
    // 刷新
    refresh () {
      let _this = this;
      let params = {
        rolekeys: ['ROLE_AD', 'ROLE_EXTEND_EMBED_ADMIN', 'ROLE_EXTEND_EMBED_MTN'],
        userName: _this.filterSearch.userName,
        tenantName: _this.filterSearch.tenantName,
        limit: _this.page.pageSize,
        offset: (_this.page.page - 1) * _this.page.pageSize
      };
      _this.$http.post({
        url: '/api/sdwan/users/query',
        data: params
      }).then(res => {
        let { status, resultBody } = res;
        if (status === '0') {
          _this.page.total = resultBody.count;
          _this.dataList = resultBody.objects;
        }
      });
    },
    // 过滤显示字段
    changeColumn (columns) {
      this.columns = columns;
      this.$refs.table.doLayout();
    },
    // 切换页码 & 显示条数
    changePage (page) {
      if (page.page) {
        this.page.page = page.page;
      } else {
        this.page.page = 1;
        this.page.pageSize = page.limit;
      }
      this.refresh();
    },
    // 获取租户&角色
    roleTenants () {
      // 获取当前登录用户
      let loginUser = this.$store.state.user.user.info;
      let params = {
        limit: 0,
        offset: 0
      };
      if (loginUser.dgId === 100000) {
        params.hasDefault = true;
      } else {
        params.hasDefault = false;
      }
      this.$http.post({
        url: '/api/sdwan/tenant/getMultiDg',
        data: params
      }).then(res => {
        let { status, resultBody } = res;
        if (status === '0') {
          let { objects } = resultBody;
          this.tenantArry = objects;
          if (loginUser.dgId === 100000) {
            this.roleArry = [{
              role: 'ROLE_AD',
              roleName: '超级管理员',
              roleKey: 'ROLE_AD',
              description: '一级管理'
            }, {
              role: 'ROLE_EXTEND',
              roleName: '系统管理员',
              roleKey: 'ROLE_EXTEND_EMBED_ADMIN',
              description: '二级管理'
            }, {
              role: 'ROLE_EXTEND',
              roleName: '系统维护员',
              roleKey: 'ROLE_EXTEND_EMBED_MTN',
              description: '二级维护'
            }];
          } else {
            this.roleArry = [{
              role: 'ROLE_EXTEND',
              roleName: '系统管理员',
              roleKey: 'ROLE_EXTEND_EMBED_ADMIN',
              description: '二级管理'
            }, {
              role: 'ROLE_EXTEND',
              roleName: '系统维护员',
              roleKey: 'ROLE_EXTEND_EMBED_MTN',
              description: '二级维护'
            }];
          }
        }
      });
    },
    // 弹出框
    showDialog (type, data) {
      let _this = this;
      _this.roleTenants();
      _this.dialogTitle = type === 'add' ? '新建' : '编辑';
      _this.$nextTick(() => {
        _this.$refs['ruleForm'].clearValidate();
      });
      if (type === 'add') {
        _this.dvEdit = true;
        _this.form = {
          username: null,
          userlabel: null,
          password: null,
          tenant: [],
          role: null,
          apiToken: null,
          email: null
        };
        _this.rules.password[0].required = true;
      } else {
        // 获取当前登录用户
        let loginUser = _this.$store.state.user.user.info;
        // 判断登入用户
        if (loginUser.username !== data.row.username) {
          _this.dvEdit = true;
          let row = {
            username: data.row.username,
            userlabel: data.row.userlabel,
            password: null,
            tenant: data.row.dgId,
            role: data.row.roleKey,
            apiToken: data.row.apiToken,
            email: data.row.email
          };
          _this.form = row;
          sessionStorage.setItem('oldform', JSON.stringify(row));
          _this.rules.password[0].required = false;
        } else {
          _this.$message.warning('无法编辑登入账户！');
        }
      }
    },
    // 取消
    cancel () {
      let _this = this;
      _this.dvEdit = false;
      sessionStorage.removeItem('oldform');
    },
    onSubmit () {
      let _this = this;
      let params = {
        acl: [],
        app: 'sdwan',
        dgId: _this.form.tenant,
        enabled: true,
        funcAuthorities: [],
        password: '',
        role: '',
        roleKey: _this.form.role,
        userGroup: 1,
        userlabel: _this.form.userlabel,
        apiToken: _this.form.apiToken,
        email: _this.form.email
      };
      _this.$refs['ruleForm'].validate(async (valid) => {
        if (valid) {
          if (_this.dialogTitle === '新建') {
            // 角色
            let roleObj = _this.roleArry.find(item => {
              return item.roleKey === params.roleKey;
            });
            params.role = roleObj.role;
            // 密码
            const key = await crypto.getKey();
            const pwd = crypto.encrypt(crypto.hash(_this.form.password), key);
            params.password = pwd;
            _this.$http.post({
              url: '/api/gateway/users/' + _this.form.username,
              data: params
            }).then(res => {
              _this.$message.success('创建成功！');
              _this.dvEdit = false;
              _this.refresh();
            });
          } else {
            let update = {};
            // 角色
            let roleObj = _this.roleArry.find(item => {
              return item.roleKey === params.roleKey;
            });
            // 判断角色是否变更
            if (_this.oldform.role === _this.form.role) {
              update.role = _this.$store.state.user.user.info.role;
            } else {
              update.funcAccesses = [];
              update.role = roleObj.role;
              update.roleKey = _this.form.role;
            }
            if (_this.oldform.userlabel !== _this.form.userlabel) {
              update.userlabel = _this.form.userlabel;
            }
            if (_this.oldform.tenant !== _this.form.tenant) {
              update.dgId = _this.form.tenant;
            }
            if (_this.oldform.apiToken !== _this.form.apiToken) {
              update.apiToken = _this.form.apiToken;
            }
            if (_this.oldform.email !== _this.form.email) {
              update.email = _this.form.email;
            }
            if (_this.form.password !== '' && _this.form.password !== null && _this.form.password !== undefined) {
              // 密码
              const key = await crypto.getKey();
              const pwd = crypto.encrypt(crypto.hash(_this.form.password), key);
              update.password = pwd;
            }
            _this.$http.put({
              url: '/api/gateway/users/' + _this.form.username,
              data: update
            }).then(res => {
              _this.$message.success('更新成功！');
              _this.dvEdit = false;
              _this.refresh();
              sessionStorage.removeItem('oldform');
            });
          }
        } else {
          _this.$message.error('请检查必填项！');
          return false;
        }
      });
    },
    deleteUser (scope) {
      let _this = this;
      // 获取当前登录用户
      let loginUser = _this.$store.state.user.user.info;
      // 判断登入用户
      if (loginUser.username !== scope.row.username) {
        this.$confirm('您确认删除当前数据吗？', '提示', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'error'
        }).then(() => {
          _this.$http.deleted({
            url: '/api/gateway/users/' + scope.row.username
          }).then(res => {
            _this.$message.success('删除成功！');
            _this.refresh();
          });
        }).catch(() => {
          _this.$message.info('取消删除');
        });
      } else {
        _this.$message.warning('无法删除登入账户！');
      }

    },
    unlock (scope) {
      let _this = this;
      this.$confirm('您确定要解锁当前数据吗？', '提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'error'
      }).then(() => {
        _this.$http.post({
          url: '/api/gateway/user/sdwan/self',
          data: {
            ids: [scope.row.id]
          }
        }).then(res => {
          _this.$message.success('解锁成功！');
          _this.refresh();
        });
      }).catch(() => {
        _this.$message.info('已取消解锁');
      });
    },
    accountAll () {
      let _this = this;
      this.$confirm('您确定要进行账户异常数据全量恢复吗？', '提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'error'
      }).then(() => {
        let params = {
          limit: 0,
          offset: 0
        };
        _this.$http.post({
          url: '/api/sdwan/users/query',
          data: params
        }).then(res => {
          let { status, resultBody } = res;
          if (status === '0') {
            let arry = [];
            for (let i = 0; i < resultBody.objects.length; i++) {
              arry.push(resultBody.objects[i].id);
            }
            _this.$http.post({
              url: 'api/gateway/user/sdwan/self',
              data: {
                ids: arry
              }
            }).then(res => {
              _this.$message.success('全量恢复成功！');
              _this.refresh();
            });
          }
        });
      }).catch(() => {
        _this.$message.info('已取消全量恢复');
      });
    }
  }
};
</script>

<style lang='scss' scoped>
.page-content {
  width: 100%;
  height: 100%;

  .avatar {
    width: 50px;
    height: 50px;
    border-radius: 50%;
  }
  .table-box {
    ::v-deep .el-button {
      padding: 0;
    }
  }

  ::v-deep .el-dialog__body {
    padding-bottom: 0;
  }

  ::v-deep .el-tag {
    cursor: pointer;
  }
}
</style>